<?php
declare (strict_types = 1);
namespace app\api\controller;

use think\Request;
use think\Exception;
use think\exception\ValidateException;

use app\api\controller\BaseController;
use service\JsonService as Json;

use app\common\model\User;
use app\common\model\CheckRule;
use app\common\model\CheckClock as Clock;
use app\common\model\ApplyMissCard as Miss;
use app\common\model\ApplyExpenses;
use app\common\model\ApplyWorkOver;
use app\common\model\ApplyLeave;
use app\common\model\ApplyLeaveType;
use app\common\model\CheckApprove;
use app\common\model\SystemMenu;
use app\common\model\UserSection;
use app\common\model\UserSectionLevel;
use app\common\model\CheckImg;

use app\common\validate\CheckClockValidate;
use app\common\validate\MissCardValidate;
use app\common\validate\WorkOverValidate;
use app\common\validate\ExpensesValidate;
use app\common\validate\LeaveValidate;

class CheckController extends BaseController
{
    /**
     * 获取打卡信息
     */
    public function getUserClock()
    {
        $wifi  = Request()->param('clock_wifi', '');
        $bssid = Request()->param('bssid', '');

        $userInfo = User::getFind(['id' => $this->user_id], 'name, avatars, check_clock_id');
        if($userInfo['check_clock_id'] == 0) return Json::fail('请先设置考勤组！');

        $checkRuleInfo = CheckRule::getFind(['id' => $userInfo['check_clock_id']]);
        if($checkRuleInfo === false) return Json::fail('考勤规则不存在!');

        $checkRule = [
            'start_time' => [
                'rule_name' => '上班' . secondToHour($checkRuleInfo['start_time']),
                'time'      => Clock::getClockTime($this->user_id, 1),
            ],
            'end_time'   => [
                'rule_name' => '下班' . secondToHour($checkRuleInfo['end_time']),
                'time'      => Clock::getClockTime($this->user_id, 2),
            ]
        ];

        $clockType = Clock::getClockType($this->user_id, $wifi, $bssid);

        if($clockType === false){
            $status = -1;
        }else if($clockType > 2){
            $status = 3;
        }else{
            $status = $clockType;
        }

        $backData = [
            'user_name'      => $userInfo['name'],
            'user_avatars'   => $userInfo['avatars'],
            'check_rule_name'=> $checkRuleInfo['name'],
            'check_rule'     => $checkRule,
            'status'         => $status,
        ];

        return Json::success('ok', $backData);
    }

    /**
     * 考勤规则
     */
    public function getCheckRule()
    {
        $userInfo = User::getFind(['id' => $this->user_id]);
        if(!$userInfo) return Json::fail();

        $ruleInfo = CheckRule::getFind(['id' => $userInfo['check_clock_id']]);
        if(!$userInfo) return Json::fail();

        if($userInfo['section_id']){
            $sectionName = UserSection::getVal(['id' => $userInfo['section_id']], 'name');
            if($userInfo['section_level_id']) $sectionName .= '(' . UserSectionLevel::getVal(['id' => $userInfo['section_level_id']], 'name') . ')';
        }else{
            $sectionName = '';
        }

        $range = [1 => '办公WIFI'];

        $backData = [
            'name'         => $userInfo['name'],
            'avatars'      => $userInfo['avatars'],
            'section_name' => $sectionName,
            'check_time'   => secondToHour($ruleInfo['start_time']) . '-' . secondToHour($ruleInfo['end_time']),
            'check_range'  => $ruleInfo['check_range'] ? $range[$ruleInfo['check_range']] : '',
        ];

        return Json::success('ok', $backData);
    }

    /** 
     * 打卡
     */
    public function inClock()
    {
        $param = input('');
    
        try{
            validate(CheckClockValidate::class)->scene('add')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        $userInfo = User::getFind(['id' => $this->user_id]);
        if(!$userInfo || $userInfo['is_staff'] != 1) return Json::fail();

        /** 打卡类型 */
        $clockType = Clock::getClockType($this->user_id, $param['clock_wifi'], $param['bssid']);
        if($clockType === false) return Json::fail('状态异常!');

        /** 打卡状态 */
        $clockStatusArr = Clock::getClockStatus($this->user_id, $clockType);

        if($clockStatusArr['status'] > 0){
            $clockStatus     = $clockStatusArr['status'];
            $clockStatusTime = $clockStatusArr['data'];
        }else{
            $clockStatus     = 1;
            $clockStatusTime = $clockStatusArr['data'];
        }

        if($clockType == 1 || $clockType == 2){
            $workTime = 0;

            /** 计算工时 */
            if($clockType == 2) $workTime = Clock::getWorkTime($this->user_id);

            $addData = [
                'user_id'       => $this->user_id,
                'clock_ip'      => getIP(),
                'clock_type'    => $clockType,
                'clock_status'  => $clockStatus,
                'work_time'     => $workTime,
                'clock_wifi'    => $param['clock_wifi'],
                'clock_address' => $param['clock_address'],
                'status_time'   => $clockStatusTime,
                'create_time'   => time()
            ];

            $flag = Clock::add($addData);
        }else if($clockType !== false){
            $editData = [
                'id'            => $clockType,
                'user_id'       => $this->user_id,
                'clock_ip'      => getIP(),
                'work_time'     => Clock::getWorkTime($this->user_id),
                'clock_wifi'    => $param['clock_wifi'],
                'clock_address' => $param['clock_address'],
                'create_time'   => time(),
            ];

            $flag = Clock::edit($editData);
        }
        
        if($flag === false) return Json::fail('打卡失败！');

        $checkImgInfo = CheckImg::orderRaw('rand()')->limit(1)->find();

        $backData = [
            'user_name'  => $userInfo['name'],
            'avatars'    => $userInfo['avatars'],
            'image'      => getUrl() . $checkImgInfo['image'],
            'content'    => $checkImgInfo['content'],
            'check_time' => $clockType == 1 ? '上班' : '下班' . '打卡成功 ' . date('H:i'),
        ];
    
        return Json::success('打卡成功', $backData);
    }

    /** 
     * 外勤打卡
     */
    public function inClockOut()
    {
        $param = input('');
    
        try{
            validate(CheckClockValidate::class)->scene('add_out')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        $userInfo = User::getFind(['id' => $this->user_id]);
        if(!$userInfo || $userInfo['is_staff'] != 1) return Json::fail();

        /** 打卡类型 */
        $clockType = Clock::getClockType($this->user_id, '', '', 1);
        if($clockType === false) return Json::fail('状态异常!');

        /** 打卡状态 */
        $clockStatusArr = Clock::getClockStatus($this->user_id, $clockType);

        if($clockStatusArr['status'] > 0){
            $clockStatus     = $clockStatusArr['status'];
            $clockStatusTime = $clockStatusArr['data'];
        }else{
            $clockStatus     = 1;
            $clockStatusTime = $clockStatusArr['data'];
        }

        if($clockType == 1 || $clockType == 2){
            $workTime = 0;
            if($clockType == 2) $workTime = Clock::getWorkTime($this->user_id);

            $addData = [
                'user_id'       => $this->user_id,
                'clock_ip'      => getIP(),
                'clock_type'    => $clockType,
                'clock_status'  => $clockStatus,
                'status_time'   => $clockStatusTime,
                'is_out'        => 1,
                'work_time'     => $workTime,
                'clock_img'     => $param['clock_img'],
                'clock_address' => $param['clock_address'],
                'remarks'       => $param['remarks'],
                'create_time'   => time()
            ];

            $flag = Clock::add($addData);
        }else if($clockType !== false){
            $editData = [
                'id'            => $clockType,
                'user_id'       => $this->user_id,
                'clock_ip'      => getIP(),
                'work_time'     => Clock::getWorkTime($this->user_id),
                'clock_img'     => $param['clock_img'],
                'clock_address' => $param['clock_address'],
                'remarks'       => $param['remarks'],
                'create_time'   => time(),
            ];

            $flag = Clock::edit($editData);
        }
        
        if($flag === false) return Json::fail('打卡失败！');

        $checkImgInfo = CheckImg::orderRaw('rand()')->limit(1)->find();

        $backData = [
            'user_name'  => $userInfo['name'],
            'avatars'    => $userInfo['avatars'],
            'image'      => getUrl() . $checkImgInfo['image'],
            'content'    => $checkImgInfo['content'],
            'check_time' => $clockType == 1 ? '上班' : '下班' . '打卡成功 ' . date('H:i'),
        ];
    
        return Json::success('打卡成功', $backData);
    }

    /**
     * 每日记录
     */
    public function getCheckDayData()
    {
        $param = input('');

        try{
            validate(CheckClockValidate::class)->scene('check_data')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        $list = Clock::getCheckDays($this->user_id, $param['days']);
        if($list === false) return Json::fail('暂无数据');

        return Json::success('ok', $list);
    }

    /**
     * 考勤统计
     */
    public function getCheckData()
    {
        $param = input('');

        try{
            validate(CheckClockValidate::class)->scene('check_data')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        $backData = [
            'work_time_avg'     => Clock::getWorkTimeAvg($this->user_id, $param['days']),
            'work_days'         => Clock::getClockDays($this->user_id, $param['days']),
            'rest_nums'         => Clock::getRestNums($this->user_id, $param['days']),
            'late_nums'         => Clock::getLateNums($this->user_id, $param['days']),
            'early_nums'        => Clock::getEarlyNums($this->user_id, $param['days']),
            'miss_card_nums'    => Clock::getMissCardNums($this->user_id, $param['days']),
            'work_neglect_nums' => Clock::getWorkNeglectNums($this->user_id, $param['days']),
            'clock_out_nums'    => Clock::getClockOutNums($this->user_id, $param['days']),
            'work_over_nums'    => Clock::getWorkOverNums($this->user_id, $param['days']),
        ];

        return Json::success('ok', $backData);
    }

    /**
     * 考勤记录
     */
    public function getCheckRecord()
    {
        $type = Request()->param('type', 0);
        $days = Request()->param('days', date('Y-m', time()));

        switch ($type) {
            case 1:
                /** 工时记录 */
                $list = Clock::getWorkTimeRecord($this->user_id, $days);
                break;
            case 2:
                /** 出勤记录 */
                $list = Clock::getWorkDaysRecord($this->user_id, $days);
                break;
            case 3:
                /** 休息记录 */
                $list = Clock::getRestNums($this->user_id, $days, 1);
                break;
            case 4:
                /** 迟到记录 */
                $list = Clock::getLateNums($this->user_id, $days, 1);
                break;
            case 5:
                /** 早退记录 */
                $list = Clock::getEarlyNums($this->user_id, $days, 1);
                break;
            case 6:
                /** 缺卡记录 */
                $list = Clock::getMissCardNums($this->user_id, $days, 1);
                break;
            case 7:
                /** 外勤记录 */
                $list = Clock::getClockOutNums($this->user_id, $days, 1);
                break;
            case 8:
                /** 旷工记录 */
                $list = Clock::getWorkNeglectNums($this->user_id, $days, 1);
                break;
            case 9:
                /** 加班记录 */
                $list = Clock::getWorkOverNums($this->user_id, $days, 1);
                break;
            default:
                return Json::fail('类型错误');
                break;
        }

        if(!$list) return Json::fail('暂无数据');
        return Json::success('ok', $list);
    }

    /**
     * 补卡申请
     */
    public function setMissCard()
    {
        $param = input('');

        try{
            validate(MissCardValidate::class)->scene('add')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        if(strtotime($param['times']) > time()) return Json::fail('时间选的不对哦^_^');

        $userInfo = User::getFind(['id' => $this->user_id]);

        $checkRuleInfo = CheckRule::getFind(['id' => $userInfo['check_clock_id']]);
        if($checkRuleInfo === false) return Json::fail('考勤组异常');

        /** 目标时间 */
        $time = strtotime($param['times']);

        /** 补卡日期 */
        $days = date('Y-m-d', strtotime($param['times']));

        /** 补卡时间 */
        // $missTime = date('H:i', strtotime($param['times']));
        $missTime = strtotime($param['times']) - strtotime($days);

        $week = [1 => '星期一', 2 => '星期二', 3 => '星期三', 4 => '星期四', 5 => '星期五', 6 => '星期六', 7 => '星期日'];

        if($missTime == $checkRuleInfo['start_time'] || $missTime < $checkRuleInfo['start_time']){
            $clockType = 1;
            $makeShift = $days . ',（' . $week[date('N', $time)] . '）,' . $checkRuleInfo['name'] . ',上班时间 ' . secondToHour($checkRuleInfo['start_time']);
        }else if($missTime == $checkRuleInfo['end_time'] || $missTime > $checkRuleInfo['end_time']){
            $clockType = 2;
            $makeShift = $days . ',（' . $week[date('N', $time)] . '）,' . $checkRuleInfo['name'] . ',上班时间 ' . secondToHour($checkRuleInfo['end_time']);
        }else{
            return Json::fail('补卡班次错误');
        }

        $searchWhere = [
            ['times', 'between', [strtotime($days), strtotime($days) + 86399]],
            ['clock_type', '=', $clockType],
            ['status', 'in', [1, 2]]
        ];

        if(Miss::getFind($searchWhere) !== false) return Json::fail('请勿重复提交申请');

        $clockInfo = Clock::where(['user_id' => $this->user_id, 'clock_type' => $clockType])->whereDay('create_time', $days)->find();
        if($clockInfo !== false && $clockInfo['clock_status'] == 1) return Json::fail('当前班次无异常'); 

        $approveInfo = CheckApprove::getFind(['section_id' => $userInfo['section_id']]);

        $data = [
            'user_id'    => $this->user_id,
            'apply_no'   => date('YmdHis') . rand(1000, 9999),
            'times'      => strtotime($param['times']),
            'clock_type' => $clockType,
            'make_shift' => $makeShift,
            'remarks'    => $param['remarks'],
            'img'        => isset($param['img']) ? $param['img'] : '',
            'approve_id' => $approveInfo['approve_id'],
            'send_id'    => $approveInfo['send_id'],
        ];

        $flag = Miss::add($data);
        if($flag === false) return Json::fail('提交申请失败');

        SystemMenu::setRed(array_unique([1, $approveInfo['approve_id']]), $this->user_id, 23, 2, $flag['id']);

        return Json::success('提交申请成功', ['id' => $flag['id']]);
    }

    /**
     * 补卡申请列表
     */
    public function getMissCardList()
    {
        $page = Request()->param('page', 1);
        $type = Request()->param('type', 1);

        if($type == 1){
            $where[] = ['user_id', '=', $this->user_id];
        }else{
            $sectionId = User::getVal(['id' => $this->user_id], 'section_id');
            $userIds   = User::getCol([['section_id', '=', $sectionId], ['status', '=', 1]], 'id');

            $where = '(approve_id=' . $this->user_id . ' and status=1 or status=2) or (send_id=' . $this->user_id . ' and status=2)';
            $where .= ' and user_id in (' . implode(',', $userIds) . ')';
        }

        $field = 'id, user_id, times, remarks, status, approve_id, send_id, create_time';
        $list = Miss::getList($where, 1, $page, 20, $field, 'create_time DESC');
        if($list === false) return Json::fail('暂无数据~');

        foreach($list as &$info){
            $userInfo = User::getFind(['id' => $info['user_id']], 'name, avatars');

            $info['times']        = date('Y-m-d H:i', $info['times']);
            $info['user_name']    = $userInfo['name'];
            $info['user_avatars'] = $userInfo['avatars'];
            $info['approve']      = User::getFind(['id' => $info['approve_id']], 'name, avatars');
            $info['send']         = User::getFind(['id' => $info['send_id']], 'name, avatars');

            unset($info['user_id']);
        }

        return Json::success('ok', $list, Miss::getNum($where));
    }

    /**
     * 补卡申请详情
     */
    public function getMissCardShow()
    {
        $id = Request()->param('id', 0);
        if($id === 0) return Json::fail('参数错误！');

        $field = 'id, user_id, apply_no, times, remarks, make_shift, approve_id, send_id, status, create_time, finish_time';
        $info = Miss::getFind(['id' => $id], $field);
        if($info === false) return Json::fail('暂无数据~');

        /** 申请人信息 */
        $userInfo = User::getFind(['id' => $info['user_id']], 'name, avatars, check_clock_id');

        /** 考勤组信息 */
        $checkRuleInfo = CheckRule::getFind(['id' => $userInfo['check_clock_id']]);

        $info['times']           = date('Y-m-d H:i', $info['times']);
        $info['section']         = isset($checkRuleInfo['name']) ? $checkRuleInfo['name'] : '';
        $info['user_name']       = $userInfo['name'];
        $info['user_avatars']    = $userInfo['avatars'];
        $info['approve']         = User::getFind(['id' => $info['approve_id']], 'name, avatars');
        $info['send']            = User::getFind(['id' => $info['send_id']], 'name, avatars');

        return Json::success('ok', $info);
    }

    /**
     * 补卡申请撤销
     */
    public function setRevokeMissCard()
    {
        $id = Request()->param('id', 0);
        if($id === 0) return Json::fail('参数错误！');

        $info = Miss::getFind(['id' => $id, 'user_id' => $this->user_id]);
        if($info === false) return Json::fail('暂无数据~');
        if($info['status'] != 1) return Json::fail('状态异常！');

        $flag = Miss::edit(['id' => $info['id'], 'status' => 4, 'finish_time' => time()]);

        if($flag === false) return Json::fail('撤销失败');
        return Json::success('撤销成功');
    }

    /**
     * 报销申请
     */
    public function setExpenses()
    {
        $param = input('');

        try{
            validate(ExpensesValidate::class)->scene('add')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        $approveInfo = CheckApprove::getApproveInfo($this->user_id);

        $data = [
            'user_id'    => $this->user_id,
            'apply_no'   => date('YmdHis') . rand(1000, 9999),
            'amount'     => $param['amount'],
            'times'      => strtotime($param['times']),
            'type'       => $param['type'],
            'desc'       => $param['desc'],
            'img'        => $param['img'],
            'approve_id' => $approveInfo['approve_id'],
            'send_id'    => $approveInfo['send_id'],
        ];

        $flag = ApplyExpenses::add($data);
        if($flag === false) return Json::fail('提交申请失败');

        SystemMenu::setRed(array_unique([1, $approveInfo['approve_id']]), $this->user_id, 22, 2, $flag['id']);
        return Json::success('提交申请成功', ['id' => $flag['id']]);
    }

    /**
     * 报销申请列表
     */
    public function getExpensesList()
    {
        $page = Request()->param('page', 1);
        $type = Request()->param('type', 1);

        if($type == 1){
            $where[] = ['user_id', '=', $this->user_id];
        }else{
            $sectionId = User::getVal(['id' => $this->user_id], 'section_id');
            $userIds   = User::getCol([['section_id', '=', $sectionId], ['status', '=', 1]], 'id');

            $where = '(approve_id=' . $this->user_id . ' and status=1 or status=2) or (send_id=' . $this->user_id . ' and status=2)';
            $where .= ' and user_id in (' . implode(',', $userIds) . ')';
        }

        $field = 'id, user_id, amount, times, type, status, approve_id, send_id, create_time';
        $list = ApplyExpenses::getList($where, 1, $page, 20, $field, 'create_time DESC');
        if($list === false) return Json::fail('暂无数据~');

        $type = ['其他', '公司花销'];

        foreach($list as &$info){
            $userInfo = User::getFind(['id' => $info['user_id']], 'name, avatars');

            $info['times']        = date('Y-m-d H:i', $info['times']);
            $info['type']         = $type[$info['type']];
            $info['user_name']    = $userInfo['name'];
            $info['user_avatars'] = $userInfo['avatars'];
            $info['approve']      = User::getFind(['id' => $info['approve_id']], 'name, avatars');
            $info['send']         = User::getFind(['id' => $info['send_id']], 'name, avatars');

            unset($info['user_id']);
        }

        return Json::success('ok', $list, ApplyExpenses::getNum($where));
    }

    /**
     * 报销申请详情
     */
    public function getExpensesShow()
    {
        $id = Request()->param('id', 0);
        if($id === 0) return Json::fail('参数错误');

        $field = 'id, user_id, apply_no, amount, times, type, desc, img, approve_id, send_id, status, create_time, finish_time';
        $info = ApplyExpenses::getFind(['id' => $id], $field);
        if($info === false) return Json::fail('暂无数据~');

        /** 申请人信息 */
        $userInfo = User::getFind(['id' => $info['user_id']], 'name, avatars, check_clock_id');

        /** 考勤组信息 */
        $checkRuleInfo = CheckRule::getFind(['id' => $userInfo['check_clock_id']]);

        $info['times']           = date('Y-m-d H:i', $info['times']);
        $info['section']         = isset($checkRuleInfo['name']) ? $checkRuleInfo['name'] : '';
        $info['user_name']       = $userInfo['name'];
        $info['user_avatars']    = $userInfo['avatars'];
        $info['approve']         = User::getFind(['id' => $info['approve_id']], 'name, avatars');
        $info['send']            = User::getFind(['id' => $info['send_id']], 'name, avatars');

        return Json::success('ok', $info);
    }

    /**
     * 报销申请撤销
     */
    public function setRevokeExpenses()
    {
        $id = Request()->param('id', 0);
        if($id === 0) return Json::fail('参数错误！');

        $info = ApplyExpenses::getFind(['id' => $id, 'user_id' => $this->user_id]);
        if($info === false) return Json::fail('暂无数据~');
        if($info['status'] != 1) return Json::fail('状态异常！');

        $flag = ApplyExpenses::edit(['id' => $info['id'], 'status' => 4, 'finish_time' => time()]);

        if($flag === false) return Json::fail('撤销失败');
        return Json::success('撤销成功');
    }

    /**
     * 加班申请
     */
    public function setWorkOver()
    {
        $param = input('');

        try{
            validate(WorkOverValidate::class)->scene('add')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        $approveInfo = CheckApprove::getApproveInfo($this->user_id);

        $data = [
            'user_id'    => $this->user_id,
            'apply_no'   => date('YmdHis') . rand(1000, 9999),
            'start_time' => strtotime($param['start_time']),
            'end_time'   => strtotime($param['end_time']),
            'duration'   => $param['duration'],
            'reason'     => $param['reason'],
            'approve_id' => $approveInfo['approve_id'],
            'send_id'    => $approveInfo['send_id'],
        ];

        $flag = ApplyWorkOver::add($data);
        if($flag === false) return Json::fail('提交申请失败');

        SystemMenu::setRed(array_unique([1, $approveInfo['approve_id']]), $this->user_id, 24, 2, $flag['id']);
        return Json::success('提交申请成功', ['id' => $flag['id']]);
    }

    /**
     * 加班申请列表
     */
    public function getWorkOverList()
    {
        $page = Request()->param('page', 1);
        $type = Request()->param('type', 1);

        if($type == 1){
            $where[] = ['user_id', '=', $this->user_id];
        }else{
            $sectionId = User::getVal(['id' => $this->user_id], 'section_id');
            $userIds   = User::getCol([['section_id', '=', $sectionId], ['status', '=', 1]], 'id');

            $where = '(approve_id=' . $this->user_id . ' and status=1 or status=2) or (send_id=' . $this->user_id . ' and status=2)';
            $where .= ' and user_id in (' . implode(',', $userIds) . ')';
        }

        $field = 'id, user_id, start_time, end_time, status, approve_id, send_id, create_time';
        $list = ApplyWorkOver::getList($where, 1, $page, 20, $field, 'create_time DESC');
        if($list === false) return Json::fail('暂无数据~');

        foreach($list as &$info){
            $userInfo = User::getFind(['id' => $info['user_id']], 'name, avatars');

            $info['start_time']   = date('Y-m-d H:i', $info['start_time']);
            $info['end_time']     = date('Y-m-d H:i', $info['end_time']);
            $info['user_name']    = $userInfo['name'];
            $info['user_avatars'] = $userInfo['avatars'];
            $info['approve']      = User::getFind(['id' => $info['approve_id']], 'name, avatars');
            $info['send']         = User::getFind(['id' => $info['send_id']], 'name, avatars');

            unset($info['user_id']);
        }

        return Json::success('ok', $list, ApplyWorkOver::getNum($where));
    }

    /**
     * 加班申请详情
     */
    public function getWorkOverShow()
    {
        $id = Request()->param('id', 0);
        if($id === 0) return Json::fail('参数错误');

        $field = 'id, user_id, apply_no, start_time, end_time, duration, reason, approve_id, send_id, status, create_time, finish_time';
        $info = ApplyWorkOver::getFind(['id' => $id], $field);
        if($info === false) return Json::fail('暂无数据~');

        /** 申请人信息 */
        $userInfo = User::getFind(['id' => $info['user_id']], 'name, avatars, check_clock_id');

        /** 考勤组信息 */
        $checkRuleInfo = CheckRule::getFind(['id' => $userInfo['check_clock_id']]);

        $info['start_time']      = date('Y-m-d H:i', $info['start_time']);
        $info['end_time']        = date('Y-m-d H:i', $info['end_time']);
        $info['section']         = isset($checkRuleInfo['name']) ? $checkRuleInfo['name'] : '';
        $info['user_name']       = $userInfo['name'];
        $info['user_avatars']    = $userInfo['avatars'];
        $info['approve']         = User::getFind(['id' => $info['approve_id']], 'name, avatars');
        $info['send']            = User::getFind(['id' => $info['send_id']], 'name, avatars');

        return Json::success('ok', $info);
    }

    /**
     * 加班申请撤销
     */
    public function setRevokeWorkOver()
    {
        $id = Request()->param('id', 0);
        if($id === 0) return Json::fail('参数错误！');

        $info = ApplyWorkOver::getFind(['id' => $id, 'user_id' => $this->user_id]);
        if($info === false) return Json::fail('暂无数据~');
        if($info['status'] != 1) return Json::fail('状态异常！');

        $flag = ApplyWorkOver::edit(['id' => $info['id'], 'status' => 4, 'finish_time' => time()]);

        if($flag === false) return Json::fail('撤销失败');
        return Json::success('撤销成功');
    }

    /**
     * 获取请假类型
     */
    public function getLeaveType()
    {
        return Json::success('ok', ApplyLeaveType::getList([], 0));
    }

    /**
     * 请假申请
     */
    public function setLeave()
    {
        $param = input('');

        try{
            validate(LeaveValidate::class)->scene('add')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        $type = ApplyLeaveType::getVal(['id' => $param['leave_type_id']], 'type');

        $duration = Clock::getLeaveTime($this->user_id, $param['start_time'], $param['end_time'], $type);
        if($duration['status'] == -1) return Json::fail($duration['msg']);

        $approveInfo = CheckApprove::getApproveInfo($this->user_id);

        $data = [
            'user_id'       => $this->user_id,
            'leave_type_id' => $param['leave_type_id'],
            'leave_type'    => $type,
            'apply_no'      => date('YmdHis') . rand(1000, 9999),
            'start_time'    => strtotime($param['start_time']),
            'end_time'      => strtotime($param['end_time']),
            'duration'      => $duration['data']['duration'],
            'duration_type' => $duration['data']['type'],
            'reason'        => isset($param['reason']) ? $param['reason'] : '',
            'img'           => isset($param['img']) ? $param['img'] : '',
            'approve_id'    => $approveInfo['approve_id'],
            'send_id'       => $approveInfo['send_id'],
        ];

        $flag = ApplyLeave::add($data);
        if($flag === false) return Json::fail('提交申请失败');

        SystemMenu::setRed(array_unique([1, $approveInfo['approve_id']]), $this->user_id, 21, 2, $flag['id']);
        return Json::success('提交申请成功', ['id' => $flag['id']]);
    }

    /**
     * 请假申请列表
     */
    public function getLeaveList()
    {
        $page = Request()->param('page', 1);
        $type = Request()->param('type', 1);

        if($type == 1){
            $where[] = ['user_id', '=', $this->user_id];
        }else{
            $sectionId = User::getVal(['id' => $this->user_id], 'section_id');
            $userIds   = User::getCol([['section_id', '=', $sectionId], ['status', '=', 1]], 'id');

            $where = '(approve_id=' . $this->user_id . ' and status=1 or status=2) or (send_id=' . $this->user_id . ' and status=2)';
            $where .= ' and user_id in (' . implode(',', $userIds) . ')';
        }

        $field = 'id, user_id, leave_type_id, approve_id, send_id, start_time, end_time, status, create_time';
        $list = ApplyLeave::getList($where, 1, $page, 20, $field, 'create_time DESC');
        if($list === false) return Json::fail('暂无数据~');

        foreach($list as &$info){
            $userInfo = User::getFind(['id' => $info['user_id']], 'name, avatars');

            $info['leave_type']   = ApplyLeaveType::getVal(['id' => $info['leave_type_id']], 'name');
            $info['start_time']   = date('Y-m-d H:i', $info['start_time']);
            $info['end_time']     = date('Y-m-d H:i', $info['end_time']);
            $info['user_name']    = $userInfo['name'];
            $info['user_avatars'] = $userInfo['avatars'];
            $info['approve']      = User::getFind(['id' => $info['approve_id']], 'name, avatars');
            $info['send']         = User::getFind(['id' => $info['send_id']], 'name, avatars');

            unset($info['user_id']);
            unset($info['leave_type_id']);
        }

        return Json::success('ok', $list, ApplyLeave::getNum($where));
    }

    /**
     * 请假申请详情
     */
    public function geLeaveShow()
    {
        $id = Request()->param('id', 0);
        if($id === 0) return Json::fail('参数错误');

        $info = ApplyLeave::getFind(['id' => $id]);
        if($info === false) return Json::fail('暂无数据~');

        /** 申请人信息 */
        $userInfo = User::getFind(['id' => $info['user_id']], 'name, avatars, check_clock_id');

        /** 考勤组信息 */
        $checkRuleInfo = CheckRule::getFind(['id' => $userInfo['check_clock_id']]);

        $info['type']            = ApplyLeaveType::getVal(['id' => $info['leave_type_id']], 'name');
        $info['start_time']      = date('Y-m-d H:i', $info['start_time']);
        $info['end_time']        = date('Y-m-d H:i', $info['end_time']);
        $info['section']         = isset($checkRuleInfo['name']) ? $checkRuleInfo['name'] : '';
        $info['user_name']       = $userInfo['name'];
        $info['user_avatars']    = $userInfo['avatars'];
        $info['approve']         = User::getFind(['id' => $info['approve_id']], 'name, avatars');
        $info['send']            = User::getFind(['id' => $info['send_id']], 'name, avatars');

        return Json::success('ok', $info);
    }

    /**
     * 请假申请撤销
     */
    public function setRevokeLeave()
    {
        $id = Request()->param('id', 0);
        if($id === 0) return Json::fail('参数错误！');

        $info = ApplyLeave::getFind(['id' => $id, 'user_id' => $this->user_id]);
        if($info === false) return Json::fail('暂无数据~');
        if($info['status'] != 1) return Json::fail('状态异常！');

        $flag = ApplyLeave::edit(['id' => $info['id'], 'status' => 4, 'finish_time' => time()]);

        if($flag === false) return Json::fail('撤销失败');

        SystemMenu::delRed($info['user_id'], 21, 2, 2, $id);
        return Json::success('撤销成功');
    }

    /**
     * 获取考勤审批信息
     */
    public function getApproveInfo()
    {
        return Json::success('ok', CheckApprove::getApproveInfo($this->user_id));
    }
}